package 图论.飞地的数量_1020;

import java.util.ArrayDeque;
import java.util.Deque;

/*给你一个大小为 m x n 的二进制矩阵 grid ，其中 0 表示一个海洋单元格、1 表示一个陆地单元格。
一次 移动 是指从一个陆地单元格走到另一个相邻（上、下、左、右）的陆地单元格或跨过 grid 的边界。
返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。

示例 1：
输入：grid = [[0,0,0,0],[1,0,1,0],[0,1,1,0],[0,0,0,0]]
输出：3
解释：有三个 1 被 0 包围。一个 1 没有被包围，因为它在边界上。

示例 2：
输入：grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
输出：0
解释：所有 1 都在边界上或可以到达边界。
* */
public class Solution1 {
    static boolean[][] visit;
    static int ans;
    static int[][] f = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
    static boolean[][] flag;

    public static void main(String[] args) {
        int[][] grid = {{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}};
//        grid = [[0,1,1,0],[0,0,1,0],[0,0,1,0],[0,0,0,0]]
        System.out.println(numEnclaves(grid));
    }

    public static int numEnclaves(int[][] grid) {
        visit = new boolean[grid.length][grid[0].length];
        flag = new boolean[grid.length][grid[0].length];;
        for (int i = 0; i < grid.length; i ++){
           flag[i][0] = true;
           flag[i][grid[0].length - 1] = true;
        }
        for (int j = 0; j < grid[0].length; j ++){
            flag[0][j] = true;
            flag[grid.length - 1][j] = true;
        }
        for (int i = 0; i < grid.length; i ++){
            for (int j = 0; j < grid[0].length; j ++){
                if (!visit[i][j] && grid[i][j] == 1){
                    bfs(grid,visit, i , j);
                }
            }
        }
        for (int i = 0; i < grid.length; i ++){
            for (int j = 0; j < grid[0].length; j ++){
                if (!flag[i][j] && grid[i][j] == 1){
                    ans ++;
                }
            }
        }
        return ans;
    }

        static void bfs(int[][] grid,boolean visit[][], int x, int y){
            Deque<int[]> queue = new ArrayDeque<>();
            queue.offer(new int[]{x, y});
            visit[x][y] = true;
            while (!queue.isEmpty()){
                int[] t = queue.poll();
                for (int i = 0; i < 4; i ++){
                    int dx = f[i][0] + t[0]; int dy = f[i][1] + t[1];
                    if (dx < 0 || dx >= grid.length || dy < 0 || dy >= grid[0].length){
                        continue;
                    }
                    if (!visit[dx][dy] && grid[dx][dy] == 1){
                        queue.offer(new int[] {dx, dy});
                        visit[dx][dy] = true;
                        if (flag[t[0]][t[1]]){
                            flag[dx][dy] = true;
                        }
                    }
                }
            }
        }
}
